package com.lgCore.clientHandler;


import com.lgCore.client.NettyClientBootstrap;
import com.lgCore.common.ClientSession;
import com.lgCore.protoModel.ProtoMsg;
import com.lgCore.util.ProtoByteUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

public class HeartBeatClientHandler extends ChannelInboundHandlerAdapter {
    Logger log = LoggerFactory.getLogger(HeartBeatClientHandler.class);
    //心跳的时间间隔，单位为秒
    private static final int HEARTBEAT_INTERVAL = 30;

    //在Handler被加入到Pipeline时，开始发送心跳
    @Override
    public void handlerAdded(ChannelHandlerContext ctx)
            throws Exception {
        ClientSession session = ClientSession.getSession(ctx);
        String clientId = session.getClientId();

        ProtoMsg.Message.Builder message = ProtoMsg.Message.newBuilder();
        ProtoMsg.HeartRequest.Builder heartRequest = ProtoMsg.HeartRequest.newBuilder();
        heartRequest.setClientId(clientId);
        heartRequest.setType(ProtoMsg.HeadType.HEART_REQUEST);
        message.setHeartRequest(heartRequest);
        //发送心跳
        heartBeat(ctx, message.build());
    }

    //使用定时器，发送心跳报文
    public void heartBeat(ChannelHandlerContext ctx,
                          ProtoMsg.Message heartbeatMsg) {
        ctx.executor().schedule(() -> {
            if (ctx.channel().isActive()) {
                log.info(" 发送 HEART_BEAT  消息 to server");
                ctx.writeAndFlush(ProtoByteUtil.protoToByte(heartbeatMsg.toBuilder()));
                //递归调用，发送下一次的心跳
                heartBeat(ctx, heartbeatMsg);
            }

        }, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
    }

    /**
     * 接受到服务器的心跳回写
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //判断消息实例
        if (null == msg || !(msg instanceof ProtoMsg.Message)) {
            super.channelRead(ctx, msg);
            return;
        }
        //判断类型
        ProtoMsg.Message pkg = (ProtoMsg.Message) msg;
        ProtoMsg.HeartResponse heartResponse = pkg.getHeartResponse();
        if (ProtoMsg.HeadType.HEART_RESPONSE.getNumber()==heartResponse.getType().getNumber()) {
            log.info(" 收到回写的 HEART_BEAT  消息 from server");
            return;
        } else {
            super.channelRead(ctx, msg);
        }
    }

}
